﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using AmuTools;
using app.Models;

namespace app.Controllers
{
    public class ApiRegister
    {
        #region 基础操作，通常无需修改，包括接口总注册和数据库配置
        public static ApiHelper<ApiContext> ah { get; set; }
        public static SqlHelper DB { get; set; }

        // 此函数将在运行一开始就执行
        public static void Do()
        {
            // 注册接口路由
            ApiUnit<ApiContext> root = new ApiUnit<ApiContext>("api", "this is the api root");
            RegisterAll(root);
            // 将接口路由注册到ApiHelper上，将来通过ah访问所有接口
            ah = new ApiHelper<ApiContext>();
            ah.Register(root);
            // 创建SqlHelper实体类，将来通过DB来访问数据库
            //DB = new SqlHelper("202.206.249.15", "OS", "sa", "wtruanjian415*");
            //香港服务器数据库信息
            //DB = new SqlHelper(".", "OS", "sa", "12#$as");
            DB = new SqlHelper(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);

        }
        #endregion

        #region 所有的接口注册在这里
        private static void RegisterAll(IApiUnit<ApiContext> root)
        {
            // 首先注册与业务基本无关的接口
            /*************************************************************************************************************************/
            RegisterCommon(root.Register("common", "与业务基本无关的接口，如API文档、状态码、Model文档、自动生成数据库"));

            // 下面开始注册所有业务相关接口啦
            /*************************************************************************************************************************/
            RegisterCourseInfo(root.Register("course_info", "所有与课程信息有关的接口"));
            RegisterTeacherInfo(root.Register("teacher_info", "所有与教师信息有关的接口"));
            RegisterAboutInfo(root.Register("about_info", "课程简介、教学大纲、考试大纲有关的接口"));
            RegisterExpand(root.Register("expand", "知识拓展相关内容有关的接口"));
            RegisterAnnouncement(root.Register("announcement", "通知公告相关内容有关的接口"));
            RegisterTutorshipInfo(root.Register("tutorship_info", "辅导资源相关内容有关的接口"));
            RegisterTest(root.Register("test", "测试接口"));
            RegisterAllInOne(root.Register("all_in_one", "测试接口"));
        }
        #endregion

        #region 要注册的子接口
        private static void RegisterCourseInfo(IApiUnit<ApiContext> root)
        {
            /**********************************************************/
            root.Register<ObjectResult>("list", "获取课程列表")
                .Body(ctx =>
                {
                    List<CourseInfo> list = DB.Get<CourseInfo>().GetFirstTableList();
                    return new ObjectResult { data = list };
                });

            /**********************************************************/
            root.Register<ObjectResult>("get", "根据用户ID获取课程信息")
                .AddArg(new StrArg { Name = "id", Descrpition = "用户ID", Default = "0", Example = "35654776" })
                .Return("返回课程")
                .Body(ctx => {
                    string id = (string)ctx.Args["id"];
                    CourseInfo ci = DB.GetById<CourseInfo>(id);
                    return new ObjectResult { data = ci };
                });

            /**********************************************************/
            root.Register<IDResult>("add", "添加新课程")
                .AddArg(new StrArg { Name = "term", Descrpition = "课程名字", Example = "张三" })
                .AddArg(new IntArg { Name = "age", Descrpition = "用户年龄", Example = 15 })
                .Return("返回新课程的ID", new IDResult { id = "5634366587" })
                .Body(ctx => {
                    string term = (string)ctx.Args["term"];
                    int age = (int)ctx.Args["age"];
                    CourseInfo ci = new CourseInfo {
                        term = term
                    };
                    DB.Insert<CourseInfo>(ci);
                    return new IDResult { id = ci.id };
                });
        }

        private static void RegisterTeacherInfo(IApiUnit<ApiContext> root)
        {
            /**********************************************************/
            root.Register<ObjectResult>("list", "获取老师列表")
                .Body(ctx =>
                {
                    List<TeacherInfo> list = DB.Get<TeacherInfo>().GetFirstTableList();
                    return new ObjectResult { data = list };
                });
            /**********************************************************/
            root.Register<ObjectResult>("get", "根据教师ID获取教师信息")
                .AddArg(new StrArg { Name = "id", Descrpition = "教师ID", Default = "0", Example = "35654776" })
                .Return("返回教师", new ObjectResult { data = new TeacherInfo() })
                .Body(ctx => {
                    string id = (string)ctx.Args["id"];
                    TeacherInfo o = DB.GetById<TeacherInfo>(id);
                    return new ObjectResult { data = o };
                });

        }

        private static void RegisterAboutInfo(IApiUnit<ApiContext> root)
        {
            /**********************************************************/
            root.Register<ObjectResult>("list", "获取简介列表")
                .Body(ctx =>
                {
                    List<AboutInfo> list = DB.Get<AboutInfo>().GetFirstTableList();
                    return new ObjectResult { data = list };
                });

            /**********************************************************/
            root.Register<ObjectResult>("get", "根据ID获取信息")
                .AddArg(new StrArg { Name = "id", Descrpition = "用户ID", Default = "0", Example = "35654776" })
                .Return("返回课程")
                .Body(ctx =>
                {
                    string id = (string)ctx.Args["id"];
                    AboutInfo ai = DB.GetById<AboutInfo>(id);
                    return new ObjectResult { data = ai };
                });
        }

        private static void RegisterExpand(IApiUnit<ApiContext> root)
        {
            /**********************************************************/
            root.Register<ObjectResult>("list", "获取简介列表")
                .Body(ctx =>
                {
                    List<Expand> list = DB.Get<Expand>().GetFirstTableList();
                    return new ObjectResult { data = list };
                });

            /**********************************************************/
            root.Register<ObjectResult>("get", "根据ID获取信息")
                .AddArg(new StrArg { Name = "id", Descrpition = "ID", Default = "0", Example = "35654776" })
                .Return("返回知识")
                .Body(ctx =>
                {
                    string id = (string)ctx.Args["id"];
                    Expand ct = DB.GetById<Expand>(id);
                    return new ObjectResult { data = ct };
                });
        }

        private static void RegisterAnnouncement(IApiUnit<ApiContext> root)
        {
            /**********************************************************/
            root.Register<ObjectResult>("list", "获取简介列表")
                .Body(ctx =>
                {
                    List<Announcement> list = DB.Get<Announcement>("", "id desc").GetFirstTableList();
                    return new ObjectResult { data = list };
                });

            /**********************************************************/
            root.Register<ObjectResult>("get", "根据ID获取信息")
                .AddArg(new StrArg { Name = "id", Descrpition = "ID", Default = "0", Example = "35654776" })
                .Return("返回知识")
                .Body(ctx =>
                {
                    string id = (string)ctx.Args["id"];
                    Announcement a = DB.GetById<Announcement>(id);
                    return new ObjectResult { data = a };
                });
        }

        private static void RegisterTutorshipInfo(IApiUnit<ApiContext> root)
        {
            /**********************************************************/
            root.Register<ObjectResult>("list", "获取简介列表")
                .Body(ctx =>
                {
                    List<TutorshipInfo> list = DB.Get<TutorshipInfo>("", "id desc").GetFirstTableList();
                    return new ObjectResult { data = list };
                });

            /**********************************************************/
            root.Register<ObjectResult>("get", "根据ID获取信息")
                .AddArg(new StrArg { Name = "id", Descrpition = "ID", Default = "0", Example = "35654776" })
                .Return("返回知识")
                .Body(ctx =>
                {
                    string id = (string)ctx.Args["id"];
                    TutorshipInfo ti = DB.GetById<TutorshipInfo>(id);
                    return new ObjectResult { data = ti };
                });
        }

        private static void RegisterTest(IApiUnit<ApiContext> root)
        {
            /**********************************************************/
            root.Register<ObjectResult>("test1", "这是测试1接口")
                .Return("返回字符串串先", new ObjectResult { data = "测试返回样例" })
                .Body(ctx => {
                    return new ObjectResult { data = "这是测试1接口的数据" };
                })
                .After((ctx, result) => {
                    result.data = result.data.ToString() + ",after附加";
                    return result;
                });

            /**********************************************************/
            root.Register<ObjectResult>("test2", "这是测试2接口")
                .Body(ctx => {
                    return new ObjectResult { data = "这是测试2接口的数据" };
                });
        }

        private static void RegisterCommon(IApiUnit<ApiContext> root)
        {
            /**********************************************************/
            root.Register<ObjectResult>("document", "API文档").Body(ctx => {
                return new ObjectResult { data = root.GetParent().GetApiJson() };
            });
            
            /**********************************************************/
            root.Register<ObjectResult>("status_code", "状态码").Body(ctx => {
                Dictionary<string, Dictionary<int, string>> all = new Dictionary<string, Dictionary<int, string>>();
                Dictionary<APISTATUS, string> codes;
                Dictionary<int, string> result;
                // 接口状态
                codes = new Dictionary<APISTATUS, string>();
                codes.Add(APISTATUS.OK, "成功");
                codes.Add(APISTATUS.LACK_PARAM, "缺少参数");
                codes.Add(APISTATUS.INVALID_PARAM, "无效的参数");
                codes.Add(APISTATUS.TYPEERROR_PARAM, "参数类型错误");
                codes.Add(APISTATUS.FAILED_INSERT, "更新失败");
                codes.Add(APISTATUS.FAILED_UPDATE, "成功");
                codes.Add(APISTATUS.FAILED_DELETE, "删除失败");
                codes.Add(APISTATUS.NO_RESOURCES, "找不到资源");
                codes.Add(APISTATUS.NO_PERMISSION, "没有权限");
                result = new Dictionary<int, string>();
                foreach(APISTATUS i in codes.Keys) result.Add((int)i, string.Format("【{0}】{1}", i.ToString(), codes[i]));
                all.Add("【APISTATUS】接口状态码", result);
                //
                return new ObjectResult { data = all };
            });

            // 这里注册所有数据模型
            /**********************************************************/
            List<Type> types = new List<Type>
            {
                typeof(CourseInfo),
                typeof(TeacherInfo)

            };
            /**********************************************************/
            root.Register<ObjectResult>("model_document", "数据模型文档").Body(ctx => {
                Dictionary<string, ParsedModel> pms = new Dictionary<string, ParsedModel>();
                foreach(Type i in types)
                {
                    pms.Add(i.Name, SqlHelper.GetParsedModel(i));
                }
                return new ObjectResult { data = pms };
            });

            /**********************************************************/
            root.Register<ObjectResult>("database_init", "初始化数据库，返回初始化数据库的操作日志。").Body(ctx => {
                List<string> logs = DB.CreateDataBase(types);
                return new ObjectResult { data = logs };
            });
        }

        private static void RegisterAllInOne(IApiUnit<ApiContext> root)
        {
            /**********************************************************/
            root.Register<ObjectResult>("list", "获取信息列表")

                .AddArg(new StrArg { Name = "fid", Descrpition = "FID", Default = "6", Example = "6" })
                .Return("返回类别信息")
                .Body(ctx =>
                {
                    string fid = (string)ctx.Args["fid"];
                    List<AllInOne> list = DB.Get<AllInOne>("fid="+fid, "id desc").GetFirstTableList("id,fid,title,time,date");
                    return new ObjectResult { data = list };
                })
                ;

            /**********************************************************/
            root.Register<ObjectResult>("get", "根据ID获取信息")
                .AddArg(new StrArg { Name = "id", Descrpition = "ID", Default = "0", Example = "35654776" })
                .Return("返回信息")
                .Body(ctx =>
                {
                    string id = (string)ctx.Args["id"];
                    AllInOne aio = DB.GetById<AllInOne>(id);
                    return new ObjectResult { data = aio };

                });

        }
        #endregion

        #region 辅助函数
        #endregion
    }
}